home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 176-200 / disk_189 / nethack / termcap.zoo / tgetent.c < prev    next >
C/C++ Source or Header  |  1988-07-30  |  8KB  |  322 lines

  1. /************************************************************************
  2.  *                                    *
  3.  *            Copyright (c) 1982, Fred Fish                   *
  4.  *                All Rights Reserved             *
  5.  *                                    *
  6.  *    This software and/or documentation is released for public    *
  7.  *    distribution for personal, non-commercial use only.        *
  8.  *    Limited rights to use, modify, and redistribute are hereby    *
  9.  *    granted for non-commercial purposes, provided that all        *
  10.  *    copyright notices remain intact and all changes are clearly    *
  11.  *    documented.  The author makes no warranty of any kind with    *
  12.  *    respect to this product and explicitly disclaims any implied    *
  13.  *    warranties of merchantability or fitness for any particular    *
  14.  *    purpose.                            *
  15.  *                                    *
  16.  ************************************************************************
  17.  */
  18.  
  19.  
  20. /*
  21.  *  LIBRARY FUNCTION
  22.  *
  23.  *    tgetent   load buffer with entry for specified terminal
  24.  *
  25.  *  KEY WORDS
  26.  *
  27.  *    termcap functions
  28.  *    utility routines
  29.  *
  30.  *  SYNOPSIS
  31.  *
  32.  *    int tgetent(bp,name)
  33.  *    char *bp;
  34.  *    char *name;
  35.  *
  36.  *  DESCRIPTION
  37.  *
  38.  *    Extracts the entry for terminal <name> from the termcap file
  39.  *    and places it in the character buffer <bp>.   It is currently
  40.  *    assumed that bp is at least 1024 characters.  If the entry in
  41.  *    the termcap file is larger than 1023 characters the excess
  42.  *    characters will be discarded and appropriate status will
  43.  *    be returned.
  44.  *
  45.  *    Also note that since bp is used by other termcap
  46.  *    routines, the storage associated with the termcap entry
  47.  *    cannot be freed until all termcap calls are completed.
  48.  *
  49.  *    Tgetent can be directed to look in a file other than
  50.  *    the default (/etc/termcap) by defining an environment
  51.  *    variable called TERMCAP to be the pathname of the desired
  52.  *    termcap file.  This is useful for debugging new entries.
  53.  *    NOTE: the pathname MUST begin with a '/' character.
  54.  *
  55.  *    Also, if the string assigned to TERMCAP does not begin with
  56.  *    a '/' and if the environment variable TERM matches <name> then
  57.  *    the string assigned to TERMCAP is copied to buffer <bp>
  58.  *    instead of reading a termcap file.
  59.  *
  60.  *  RETURNS
  61.  *
  62.  *    -1  if the termcap file cannot be opened
  63.  *     0  if no entry in termcap file matches <name>
  64.  *     1  if extraction is successful with no errors
  65.  *     2  if extraction is successful but entry truncated
  66.  *
  67.  *  SEE ALSO
  68.  *
  69.  *    tgetnum   extract numeric type capability
  70.  *    tgetflag  test boolean type capability
  71.  *    tgetstr   get string value of capability
  72.  *
  73.  *  AUTHOR
  74.  *
  75.  *    Fred Fish
  76.  *
  77.  */
  78.  
  79. #include <stdio.h>
  80. #include <string.h>
  81.  
  82. #define TRUE 1
  83. #define FALSE 0
  84. #define BUFSIZE 1024            /* Assumed size of external buffer */
  85.  
  86. #define NO_FILE  -1            /* Returned if can't open file */
  87. #define NO_ENTRY  0            /* Returned if can't find entry */
  88. #define SUCCESS   1            /* Returned if entry found ok */
  89. #define TRUNCATED 2            /* Returned if entry found but trunc */
  90.  
  91. # ifdef DGK
  92. # define DEFAULT_ROOT "termcap.cnf"             /* name without path component */
  93.   FILE *fopenp();
  94. # endif
  95. # define DEFAULT_FILE "/etc/termcap"    /* default termcap filename */
  96.  
  97. char *_tcpbuf;                /* Place to remember buffer pointer */
  98.  
  99. /*
  100.  *  PSEUDO CODE
  101.  *
  102.  *    Begin tgetent
  103.  *        Erase any previous buffer contents.
  104.  *        Remember the buffer pointer.
  105.  *        If termcap file is not found then
  106.  *        If buffer was filled anyway then
  107.  *            Return SUCCESS.
  108.  *        Else
  109.  *            Return NO_FILE.
  110.  *        End if
  111.  *        Else
  112.  *        While records left to process
  113.  *            If this is entry is what we want then
  114.  *            Close the termcap file.
  115.  *            If entry was truncated then
  116.  *                Return TRUNCATED status
  117.  *            Else
  118.  *                Return SUCCESS status.
  119.  *            End if
  120.  *            End if
  121.  *        End while
  122.  *        Return NO_ENTRY status.
  123.  *        End if
  124.  *    End tgetent
  125.  *
  126.  */
  127.  
  128. int tgetent(bp,name)
  129. char *bp;                /* Pointer to buffer (1024 char min) */
  130. char *name;                /* Pointer to terminal entry to find */
  131. {
  132.     FILE *fp, *find_file();
  133.  
  134.     *bp = NULL;
  135.     _tcpbuf = bp;
  136.     if ((fp = find_file(bp)) == NULL) {
  137.     if (*bp != NULL) {
  138.         return(SUCCESS);
  139.     } else {
  140.         return(NO_FILE);
  141.     }
  142.     } else {
  143.     while (fgetlr(bp,BUFSIZE,fp)) {
  144.         if (gotcha(bp,name)) {
  145.         fclose(fp);
  146.         if (bp[strlen(bp)-1] != '\n') {
  147.             return(TRUNCATED);
  148.         } else {
  149.             return(SUCCESS);
  150.         }
  151.         }
  152.     }
  153.     return(NO_ENTRY);
  154.     }
  155. }
  156.  
  157. /*
  158.  *  INTERNAL FUNCTION
  159.  *
  160.  *    find_file    find the termcap file and open it if possible
  161.  *
  162.  *  KEY WORDS
  163.  *
  164.  *    internal functions
  165.  *    find_file
  166.  *
  167.  *  SYNOPSIS
  168.  *
  169.  *    static FILE *find_file(bp)
  170.  *    char *bp;
  171.  *
  172.  *  DESCRIPTION
  173.  *
  174.  *    Attempts to locate and open the termcap file.  Also handles
  175.  *    using the environment TERMCAP string as the actual buffer
  176.  *    (that's why bp has to be an input parameter).
  177.  *
  178.  *    If TERMCAP is defined an begins with a '/' character then
  179.  *    it is taken to be the pathname of the termcap file and
  180.  *    an attempt is made to open it.    If this fails then
  181.  *    the default termcap file is used instead.
  182.  *
  183.  *    If TERMCAP is defined but does not begin with a '/' then
  184.  *    it is assumed to be the actual buffer contents provided
  185.  *    that <name> matches the environment variable TERM.
  186.  *
  187.  *  BUGS
  188.  *
  189.  *    There is currently no way to be sure which termcap
  190.  *    file was opened since the default will always be
  191.  *    tried.
  192.  *
  193.  */
  194.  
  195. /*
  196.  *  PSEUDO CODE
  197.  *
  198.  *    Begin find_file
  199.  *        If there is a TERMCAP environment string then
  200.  *        If the string is not null then
  201.  *            If the string is a pathname then
  202.  *            If that file is opened successfully then
  203.  *                Return its pointer.
  204.  *            End if
  205.  *            Else
  206.  *            If there is a TERM environment string then
  207.  *                If TERM matches <name> then
  208.  *                Copy TERMCAP string to buffer.
  209.  *                Return NULL for no file.
  210.  *                End if
  211.  *            End if
  212.  *            End if
  213.  *        End if
  214.  *        End if
  215.  *        Open default termcap file and return results.
  216.  *    End find_file
  217.  *
  218.  */
  219.  
  220. static FILE *find_file(bp)
  221. char *bp;
  222. {
  223.     FILE *fp, *fopen();
  224.     char *cp, *ncp, *getenv();
  225.  
  226.     if ((cp = getenv("TERMCAP")) != NULL) {
  227.     if (*cp != NULL) {
  228.         if (*cp == '/' || *cp == '\\') {
  229.         if ((fp = fopen(cp,"r")) != NULL) {
  230.             return(fp);
  231.         }
  232.         } else {
  233.         if ((ncp = getenv("TERM")) != NULL) {
  234.             if (strcmp(cp,ncp) == 0) {
  235.             strcpy(bp,cp);
  236.             return((FILE *)NULL);
  237.             }
  238.         }
  239.         }
  240.     }
  241.     }
  242. # ifdef DGK
  243.     /* Try current directory, then /etc/termcap, then along the path
  244.      */
  245.     if (fp = fopen(DEFAULT_ROOT, "r"))
  246.         return fp;
  247.     else if (fp = fopen(DEFAULT_FILE, "r"))
  248.         return fp;
  249.     else
  250.         return fopenp(DEFAULT_ROOT, "r", NULL);
  251. # else
  252.     return(fopen(DEFAULT_FILE,"r"));
  253. # endif
  254. }
  255.  
  256. /*
  257.  *  INTERNAL FUNCTION
  258.  *
  259.  *    gotcha     test to see if entry is for specified terminal
  260.  *
  261.  *  SYNOPSIS
  262.  *
  263.  *    gotcha(bp,name)
  264.  *    char *bp;
  265.  *    char *name;
  266.  *
  267.  *  DESCRIPTION
  268.  *
  269.  *    Tests to see if the entry in buffer bp matches the terminal
  270.  *    specified by name.  Returns TRUE if match is detected, FALSE
  271.  *    otherwise.
  272.  *
  273.  */
  274.  
  275. /*
  276.  *  PSEUDO CODE
  277.  *
  278.  *    Begin gotcha
  279.  *        If buffer character is comment character then
  280.  *        Return FALSE since remainder is comment
  281.  *        Else
  282.  *        Initialize name scan pointer.
  283.  *        Compare name and buffer until end or mismatch.
  284.  *        If valid terminators for both name and buffer strings
  285.  *            Return TRUE since a match was found.
  286.  *        Else
  287.  *            Find next non-name character in buffer.
  288.  *            If not an alternate name separater character
  289.  *            Return FALSE since no more names to check.
  290.  *            Else
  291.  *            Test next name and return results.
  292.  *            End if
  293.  *        End if
  294.  *        End if
  295.  *    End gotcha
  296.  *
  297.  */
  298.  
  299. gotcha(bp,name)
  300. char *bp;
  301. char *name;
  302. {
  303.     char *np;
  304.  
  305.     if (*bp == '#') {
  306.     return(FALSE);
  307.     } else {
  308.     np = name;
  309.     while (*np == *bp && *np != NULL) {np++; bp++;}
  310.     if (*np == NULL && (*bp == NULL || *bp == '|' || *bp == ':')) {
  311.         return(TRUE);
  312.     } else {
  313.         while (*bp != NULL && *bp != ':' && *bp != '|') {bp++;}
  314.         if (*bp != '|') {
  315.         return(FALSE);
  316.         } else {
  317.         return(gotcha(++bp,name));
  318.         }
  319.     }
  320.     }
  321. }
  322.